package cn.turboinfo.fuyang.api.domain.util;

import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.stream.Collectors;

/**
 * 打码工具类
 *
 * @author qatang
 */
public class MaskUtils {

    /**
     * 字符串打码
     *
     * @param s           待打码字符串
     * @param leftRest    左边预留
     * @param rightRest   右边预留
     * @param mosaic      替换字符
     * @param mosaicCount 替换字符长度，如果大于零则按指定数量显示替换字符个数, 否则保持原始长度
     * @return 打码后的字符串
     */
    public static String maskPartialString(String s, int leftRest, int rightRest, String mosaic, int mosaicCount) {
        int length = StringUtils.length(s);
        if (leftRest + rightRest > length) {
            // 超过长度不做打码原样返回
            return s;
        }

        String left = StringUtils.left(s, leftRest);
        String right = StringUtils.right(s, rightRest);

        String middle;
        if (mosaicCount <= 0) {
            middle = StringUtils.repeat(mosaic, length - leftRest - rightRest);
        } else {
            middle = StringUtils.repeat(mosaic, mosaicCount);
        }

        return left + middle + right;
    }

    private final static Map<Character, Character> ID_TO_MASK_MAP;
    private final static Map<Character, Character> MASK_TO_ID_MAP;

    static {
        ID_TO_MASK_MAP = Maps.newHashMap();

        ID_TO_MASK_MAP.put('a', 'E');
        ID_TO_MASK_MAP.put('b', 'N');
        ID_TO_MASK_MAP.put('c', 'm');
        ID_TO_MASK_MAP.put('d', 'y');
        ID_TO_MASK_MAP.put('e', 'M');
        ID_TO_MASK_MAP.put('f', 'G');
        ID_TO_MASK_MAP.put('g', 'L');
        ID_TO_MASK_MAP.put('h', 'k');
        ID_TO_MASK_MAP.put('i', '0');
        ID_TO_MASK_MAP.put('j', 'a');
        ID_TO_MASK_MAP.put('k', 'U');
        ID_TO_MASK_MAP.put('l', 'S');
        ID_TO_MASK_MAP.put('m', 'K');
        ID_TO_MASK_MAP.put('n', 'Z');
        ID_TO_MASK_MAP.put('o', 'b');
        ID_TO_MASK_MAP.put('p', 'h');
        ID_TO_MASK_MAP.put('q', 'A');
        ID_TO_MASK_MAP.put('r', '9');
        ID_TO_MASK_MAP.put('s', 'F');
        ID_TO_MASK_MAP.put('t', 't');
        ID_TO_MASK_MAP.put('u', 'z');
        ID_TO_MASK_MAP.put('v', 'l');
        ID_TO_MASK_MAP.put('w', 'Q');
        ID_TO_MASK_MAP.put('x', 's');
        ID_TO_MASK_MAP.put('y', 'R');
        ID_TO_MASK_MAP.put('z', 'w');
        ID_TO_MASK_MAP.put('0', 'n');
        ID_TO_MASK_MAP.put('1', 'W');
        ID_TO_MASK_MAP.put('2', 'B');
        ID_TO_MASK_MAP.put('3', 'r');
        ID_TO_MASK_MAP.put('4', '2');
        ID_TO_MASK_MAP.put('5', 'c');
        ID_TO_MASK_MAP.put('6', 'J');
        ID_TO_MASK_MAP.put('7', 'P');
        ID_TO_MASK_MAP.put('8', 'v');
        ID_TO_MASK_MAP.put('9', 'g');

        MASK_TO_ID_MAP = ID_TO_MASK_MAP.entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
    }

    public static String maskId(long id) {
        String idBase36 = Long.toString(id, 36);
        StringBuilder s = new StringBuilder();
        for (char c : idBase36.toCharArray()) {
            s.append(ID_TO_MASK_MAP.get(c));
        }
        return s.toString();
    }

    public static long unmaskId(String maskedId) {
        StringBuilder s = new StringBuilder();
        for (char c : maskedId.toCharArray()) {
            s.append(MASK_TO_ID_MAP.get(c));
        }
        return Long.valueOf(s.toString(), 36);
    }

    private final static Map<Character, Character> ID_TO_MASK_CHN_MAP;
    private final static Map<Character, Character> MASK_TO_ID_CHN_MAP;

    static {
        ID_TO_MASK_CHN_MAP = Maps.newHashMap();

        ID_TO_MASK_CHN_MAP.put('a', '嘗');
        ID_TO_MASK_CHN_MAP.put('b', '喺');
        ID_TO_MASK_CHN_MAP.put('c', '琰');
        ID_TO_MASK_CHN_MAP.put('d', '勖');
        ID_TO_MASK_CHN_MAP.put('e', '窿');
        ID_TO_MASK_CHN_MAP.put('f', '喚');
        ID_TO_MASK_CHN_MAP.put('g', '瑩');
        ID_TO_MASK_CHN_MAP.put('h', '盪');
        ID_TO_MASK_CHN_MAP.put('i', '堅');
        ID_TO_MASK_CHN_MAP.put('j', '璽');
        ID_TO_MASK_CHN_MAP.put('k', '畝');
        ID_TO_MASK_CHN_MAP.put('l', '噠');
        ID_TO_MASK_CHN_MAP.put('m', '犢');
        ID_TO_MASK_CHN_MAP.put('n', '甕');
        ID_TO_MASK_CHN_MAP.put('o', '皺');
        ID_TO_MASK_CHN_MAP.put('p', '卮');
        ID_TO_MASK_CHN_MAP.put('q', '啻');
        ID_TO_MASK_CHN_MAP.put('r', '咲');
        ID_TO_MASK_CHN_MAP.put('s', '刪');
        ID_TO_MASK_CHN_MAP.put('t', '圖');
        ID_TO_MASK_CHN_MAP.put('u', '畲');
        ID_TO_MASK_CHN_MAP.put('v', '冪');
        ID_TO_MASK_CHN_MAP.put('w', '疡');
        ID_TO_MASK_CHN_MAP.put('x', '竄');
        ID_TO_MASK_CHN_MAP.put('y', '穫');
        ID_TO_MASK_CHN_MAP.put('z', '呋');
        ID_TO_MASK_CHN_MAP.put('0', '剣');
        ID_TO_MASK_CHN_MAP.put('1', '瓊');
        ID_TO_MASK_CHN_MAP.put('2', '瑪');
        ID_TO_MASK_CHN_MAP.put('3', '労');
        ID_TO_MASK_CHN_MAP.put('4', '窺');
        ID_TO_MASK_CHN_MAP.put('5', '埵');
        ID_TO_MASK_CHN_MAP.put('6', '瓏');
        ID_TO_MASK_CHN_MAP.put('7', '甌');
        ID_TO_MASK_CHN_MAP.put('8', '竇');
        ID_TO_MASK_CHN_MAP.put('9', '冨');

        MASK_TO_ID_CHN_MAP = ID_TO_MASK_CHN_MAP.entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
    }

    public static String maskIdChn(long id) {
        if (id < 10) {
            throw new RuntimeException("id必须大于10");
        }
        String idBase36 = Long.toString(id, 36);
        StringBuilder s = new StringBuilder();
        for (char c : idBase36.toCharArray()) {
            s.append(ID_TO_MASK_CHN_MAP.get(c));
        }
        return s.toString();
    }

    public static long unmaskIdChn(String maskedId) {
        StringBuilder s = new StringBuilder();
        for (char c : maskedId.toCharArray()) {
            s.append(MASK_TO_ID_CHN_MAP.get(c));
        }
        return Long.valueOf(s.toString(), 36);
    }
}
